﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;

namespace PmSoft.Web.Abstractions.Attributes;

/// <summary>
/// 自定义授权特性，用于基于菜单权限控制访问。
/// 通过指定一个或多个菜单代码，要求当前用户拥有对应的菜单权限才能访问标记的控制器或方法。
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class MenuAuthorizeAttribute : AuthorizeAttribute
{
	/// <summary>
	/// 获取当前授权特性所需的菜单代码集合。
	/// </summary>
	public string[] RequiredPermCodes { get; }

	/// <summary>
	/// 初始化 <see cref="MenuAuthorizeAttribute"/> 的新实例，指定所需的菜单代码。
	/// </summary>
	/// <param name="permCodes">一个或多个菜单代码，表示用户必须拥有的权限。若为空或 null，则抛出异常。</param>
	/// <exception cref="ArgumentNullException">当 <paramref name="permCodes"/> 为 null 或空数组时抛出。</exception>
	public MenuAuthorizeAttribute(params string[] permCodes)
		: base("MenuPolicy") // 指定授权策略名称为 "MenuPolicy"
	{
		// 参数验证，确保传入的菜单代码有效
		if (permCodes == null || permCodes.Length == 0 || permCodes.All(string.IsNullOrWhiteSpace))
		{
			throw new ArgumentNullException(nameof(permCodes), "Perm codes cannot be null, empty, or whitespace.");
		}

		RequiredPermCodes = permCodes;
		AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme; // 使用 JWT Bearer 认证方案
	}
}